using Autofac;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Newtonsoft.Json;
using Serilog;
using SqlSugar;
using System.Reflection;
using xjjxmm.infrastructure.Common;
using XjjXmm.Infrastructure.Configuration;
using XjjXmm.Infrastructure.Constant;
using XjjXmm.Infrastructure.ToolKit;

namespace xjjxmm.infrastructure.SetUp
{
    public static class SqlStartUp
	{
		public static ContainerBuilder AddSql( ContainerBuilder builder)
        {

            var dbtype = ConfigHelper.GetConfig(CommonConstant.SqlConfigKey + ":Type");
            var connectionString = ConfigHelper.GetConfig(CommonConstant.SqlConfigKey + ":ConnectionString");
            var frameConfig = ConfigHelper.GetSection<FrameworkConfig>(CommonConstant.FrameworkConfigKey);

            Log.Information($"connectioin: {connectionString}");
           // Console.Write($"connectioin: {connectionString}");

            if (dbtype.IsNullOrEmpty() || connectionString.IsNullOrEmpty())
			{
				return builder;
			}


            builder.Register(com =>
            {
                return BuildSqlClient(connectionString!, dbtype!);
            }).AsImplementedInterfaces().SingleInstance();

            return builder;
            /*	    builder.Register(com =>
                    {
                        var sqlSugar = new SqlSugarScope(new ConnectionConfig()
                            {
                                DbType = EnumKit.Parse<DbType>(dbtype!),
                                ConnectionString = connectionString,
                                IsAutoCloseConnection = true,
                                ConfigureExternalServices = new ConfigureExternalServices
                                {
                                    //注意:  这儿AOP设置不能少
                                    EntityService = (c, p) =>
                                    {
                                        if (p.IsPrimarykey == false &&
                                            new NullabilityInfoContext().Create(c).WriteState is NullabilityState.Nullable)
                                        {
                                            p.IsNullable = true;
                                        }
                                    }
                                }
                            },
                            db =>
                            {
                                if (frameConfig?.showSql == "1")
                                {
                                    //单例参数配置，所有上下文生效
                                    db.Aop.OnLogExecuting = (sql, pars) =>
                                    {
                                        var par = pars?.Select(t => t.Value);

                                        Log.Information($"Sql:{sql}\r\n paramters: {JsonConvert.SerializeObject(par)}");
                                        //Log.Information($"Sql:{sql}\r\n paramters: {JsonConvert.SerializeObject(pars)}");
                                        //Console.WriteLine(sql);//输出sql
                                        //Console.WriteLine(string.Join(",", pars?.Select(it => it.ParameterName + ":" + it.Value)));//参数
                                    };
                                }

                                db.Aop.OnError = exception => { Log.Error(exception, "sql error"); };
                            }
                        );

                        return sqlSugar;
                    }).AsImplementedInterfaces().SingleInstance();

                return builder;*/
        }

        public static ContainerBuilder AddSql( ContainerBuilder builder, string key)
        {
            var dbtype = ConfigHelper.GetConfig(key + ":Type");
            var connectionString = ConfigHelper.GetConfig(key + ":ConnectionString");
            var frameConfig = ConfigHelper.GetSection<FrameworkConfig>(CommonConstant.FrameworkConfigKey);

            //Log.Information($"connectioin: {connectionString}");
            // Console.Write($"connectioin: {connectionString}");

            if (dbtype.IsNullOrEmpty() || connectionString.IsNullOrEmpty())
            {
                return builder;
            }



            builder.Register(com =>
            {
                return BuildSqlClient(connectionString!, dbtype!);
            }).Keyed<ISqlSugarClient>(key).AsImplementedInterfaces().SingleInstance();

            return builder;
        }


        private static SqlSugarScope BuildSqlClient(string connectionString, string dbtype)
        {
           
            var frameConfig = ConfigHelper.GetSection<FrameworkConfig>(CommonConstant.FrameworkConfigKey);

           
                var sqlSugar = new SqlSugarScope(new ConnectionConfig()
                {
                    DbType = EnumKit.Parse<DbType>(dbtype!),
                    ConnectionString = connectionString,
                    IsAutoCloseConnection = true,
                    ConfigureExternalServices = new ConfigureExternalServices
                    {
                        //注意:  这儿AOP设置不能少
                        EntityService = (c, p) =>
                        {
                            if (p.IsPrimarykey == false &&
                                new NullabilityInfoContext().Create(c).WriteState is NullabilityState.Nullable)
                            {
                                p.IsNullable = true;
                            }
                        }
                    }
                },
                    db =>
                    {
                        if (frameConfig?.ShowSql == "1")
                        {
                            //单例参数配置，所有上下文生效
                            db.Aop.OnLogExecuting = (sql, pars) =>
                            {
                                var par = pars?.Select(t => t.Value);

                                Log.Information($"Sql:{sql}\r\n paramters: {JsonConvert.SerializeObject(par)}");
                                //Log.Information($"Sql:{sql}\r\n paramters: {JsonConvert.SerializeObject(pars)}");
                                //Console.WriteLine(sql);//输出sql
                                //Console.WriteLine(string.Join(",", pars?.Select(it => it.ParameterName + ":" + it.Value)));//参数
                            };
                        }

                        db.Aop.OnError = exception => { Log.Error(exception, "sql error"); };
                    }
                );

                return sqlSugar;
           
        }
    }
}
